Skip to content

Run the published binary from the directory it was downloaded into - #225

Merged
iderex merged 1 commit into
mainfrom
release/run-the-binary-from-where-it-was-downloaded
Aug 30, 2026
Merged

Run the published binary from the directory it was downloaded into#225
iderex merged 1 commit into
mainfrom
release/run-the-binary-from-where-it-was-downloaded

Conversation

@iderex

@iderex iderex commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Refs #43.

What was wrong

.github/workflows/smoke.yml resolved the downloaded binary from inside
download/ and handed the result on through the environment file:

cd download
binary=$(find . -name "*_${ASSET}" -type f | head -1)
...
echo "BINARY=${binary}" >> "${GITHUB_ENV}"

find . from inside that directory returns ./lab_<tag>_<platform>. The
platform starts every step in the workspace and a cd lives and dies with the
step that runs it, so the step two below, which is where the binary is actually
executed, read that name one directory too high.

Why it is worth finding before a release rather than during one

The run step treats any non-zero code as the binary having refused the tree:

if [ "${code}" -ne 0 ]; then
  echo "::error::The published binary refused the default branch of this repository, or could not do its job. Record 0011 is what that code means."

So an artefact that was never executed at all would have reddened all three
matrix entries with a message about record 0011, on the first real release, and
the reading it invites is that the published binary is broken.

The evidence

Both steps stood up as separate shells from a workspace holding
download/lab_v0.0.1_linux_amd64, which is how the platform runs them. Before:

chmod: cannot access './lab_v0.0.1_linux_amd64': No such file or directory
/usr/bin/bash: line 1: ./lab_v0.0.1_linux_amd64: No such file or directory
code=127

After, against a fresh clone of this repository made by the same reproduction:

code=0
examined fresh-clone
1 experiment directory walked, 1 record read
27 decision records read
the time this run read is 2026-08-30T08:22:38Z
0 refused

The assertion block of that step, run verbatim over that log rather than
described:

every assertion in the step passes; it read 27 decision record(s)

The four legs of the gate on this branch:

go build ./cmd/... ./internal/...
go vet ./cmd/... ./internal/...
gofmt -l cmd internal
go test -count=1 ./cmd/... ./internal/...
ok  	github.com/Flowfin/lab/cmd/bom	4.157s
ok  	github.com/Flowfin/lab/cmd/contexts	0.444s
ok  	github.com/Flowfin/lab/cmd/lab	1.222s
ok  	github.com/Flowfin/lab/cmd/notices	4.566s
ok  	github.com/Flowfin/lab/cmd/pullrequest	0.480s
ok  	github.com/Flowfin/lab/internal/bom	0.700s
ok  	github.com/Flowfin/lab/internal/check	2.318s
ok  	github.com/Flowfin/lab/internal/contexts	0.873s
ok  	github.com/Flowfin/lab/internal/hardware	0.445s
ok  	github.com/Flowfin/lab/internal/invariants	1.432s
ok  	github.com/Flowfin/lab/internal/notices	0.635s
ok  	github.com/Flowfin/lab/internal/prose	0.843s
ok  	github.com/Flowfin/lab/internal/pullrequest	0.486s

gofmt -l printed nothing, which is its passing result.

The means

A one-line change to the workflow that already carries this job, because what
was wrong is a path this file computes and hands to itself. Nothing else could
carry it: the value never leaves that workflow, and moving it into the runner
would put a property of a step into a binary that knows nothing about steps.

What this does not do

It does not finish #43. The last leg of that issue's done-when is the job having
passed against a real release, and there is none:

gh api repos/Flowfin/lab/releases --jq 'length'
0

So what is repaired here is a defect in a leg that cannot run yet, found by
reading the file rather than by running it. The bound is that the reproduction
above is two shells on this machine standing in for two steps on a runner: it
reproduces the working directory the platform gives each step and it reproduces
nothing else about one, and no run of this workflow has executed either leg.

The other job in that file, verify the published artefacts, was read in the
same pass for the same class. Its three steps each cd download for themselves
and hand no path between them, so it does not carry this defect. That is a
reading rather than a run.

Nothing in this tree refuses the next one of these. Both legs of this workflow
run on a tag or on a published release, so their steps reach no pull request,
and no check here reads a shell path across steps.

Second reader

There is none tonight. The evidence above stands in place of one, and the
negative results in it are stated rather than softened.

The smoke job resolved the downloaded binary from inside `download/` and wrote
that result into the environment file as `./lab_<tag>_<platform>`. The platform
starts every step in the workspace and a `cd` lives and dies with the step that
runs it, so the step that executes the binary read the name one directory too
high and the file was not there.

What makes it worth finding before a release rather than during one is what the
failure looks like when it happens. The run step treats any non-zero code as the
binary having refused the tree, so an artefact that was never executed at all
would have reddened all three matrix entries with a message about record 0011.

Reproduced by standing the two steps up as separate shells from a workspace
holding `download/lab_v0.0.1_linux_amd64`:

    chmod: cannot access './lab_v0.0.1_linux_amd64': No such file or directory
    code=127

With the path written relative to the workspace instead, the same reproduction
executes the binary against a fresh clone of this repository and every assertion
in that step passes:

    code=0
    examined fresh-clone
    1 experiment directory walked, 1 record read
    27 decision records read
    0 refused

Nothing in this tree refuses the next one. Both legs of that workflow run on a
tag or on a published release, so their steps reach no pull request, and this
was found by reading the file rather than by a check.

Refs #43

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex iderex self-assigned this Aug 30, 2026
@iderex
iderex merged commit 8d4c281 into main Aug 30, 2026
25 checks passed
@iderex
iderex deleted the release/run-the-binary-from-where-it-was-downloaded branch August 30, 2026 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant